#usr/bin/env python
#conding:utf-8
# 吕康宁，2020.6.3
import re,os,sys
import time,datetime
import base64
import binascii
import numpy as np
import pandas as pd
# import ffmpy3

mesg_to_db_field={'lbs': '0', 'mileage': '0', 'speed': '0', 'othermesg':{}, 'wifi': '0', 
		  'oil_use': '0', 'dirct': '0', 'scanner': '0', 'rssi': '0', 'efence_alarm': '0', 
		  'status': '0', 'remark': '0', 'heart_rate': '0', 'speed_alarm': '0', 'battery': '0', 
		  'blood_pres': '0', 'stop_time': '0','sos_alarm': '0', 'step_count': '0', 
		  'heart_alarm': '0', 'device_id':'0', 'dev_upload': '0', 'obd': '0', 'blood_alarm': '0', 
		  'lng': '0', 'serv_receive': '0', 'track_type': '0', 'location': '0', 'lat': '0', 'hard_verson': '0'}

three_command_result_dict={'UPLOAD': 'send_rate', 'hrtstart': 'health_detect', 'CENTER': 'center_num_set', 
						   'CALL': 'phone_call', 'SOS1': 'sos1', 'SOS2': 'sos2', 'SOS3': 'sos3', 'SOS': 'sos', 
						   'IP': 'ip_port', 'LZ': 'time_language', 'SOSSMS': 'sosmsg_to_phone', 'LOWBAT': 'low_power_msg', 
						   'REMOVE': 'dev_remove_alarm', 'REMOVESMS': 'dev_remove_msg', 'PEDO': 'step_cunt_btn', 
						   'WALKTIME': 'walk_time_set', 'SILENCETIME': 'silence_time_set', 'REMIND': 'time_remind', 
						   'SLEEPTIME': 'sleep_time', 'profile': 'work_model', 'DPHBX': 'del_phonebook', 'CR': 'call_now', 
						   'FACTORY': 'factory_set', 'VERNO': 'verson_detail', 'RESET': 'dev_reset', 'POWEROFF': 'turn_off_dev', 
						   'FIND': 'find_dev', 'rcapture': 'photograph', 'MONITOR': 'monitor'}


def get_track_type(raw_data):
	this_track_type='0'
	if raw_data.get('lng')!=None and raw_data.get('lng')!='0':
		this_track_type='satelite'
	elif raw_data.get('wifi')!=None and raw_data.get('wifi')!='0':
		this_track_type='wifi'
	elif raw_data.get('lbs')!=None and raw_data.get('lbs')!='0':
		this_track_type='lbs'

	return this_track_type

# 把音频，图片等存储在本地的函数
def save_to_file(device_id,send_name,content,send_time):
	# 转换成时间数组
	# now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
	timeArray = time.strptime(send_time, "%Y-%m-%d %H:%M:%S")
	# 转换成时间戳
	timestamp = time.mktime(timeArray)
	# if x == 'tk_mesg':
	# 	send_name = 'amr'
	# elif x == 'img_data':
	# 	send_name = 'jpeg'
	# 获取当前设备号,获取现在的时间年月日,获取现在时间的时间戳时间,然后存入文件中
	pk_name = "{}.{}".format(int(timestamp), send_name)
	plat_form=sys.platform[0:3]
	save_path=''
	if plat_form=='win':
		save_path="E:\\tracker\\tracker_app\\static\\multi_data\\{0}\\{1}\\".format(device_id, datetime.datetime.now().strftime('%Y-%m-%d'))
	else:
		save_path="/root/tracker/tracker_app/static/multi_data/{0}/{1}/".format(device_id, datetime.datetime.now().strftime('%Y-%m-%d'))
	
	if not os.path.exists(save_path):  # 判断当前路径是否存在，没有则创建new文件夹/root/device
		os.makedirs(save_path)
	file_path=save_path + pk_name

	if send_name=='amr':
		pk_name1 = "{}.{}".format(int(timestamp), 'mp3')
		if not os.path.exists(file_path):
			with open(file_path, "wb") as f:
				f.write(content)
			
			file_path1=save_path + pk_name1
			# 判断是否存在音频文件
			if os.path.exists(file_path):
				cmd='ffmpeg -i '+file_path+' -acodec libmp3lame '+file_path1
				os.popen(cmd)
				# 会堵塞，os的popen是异步的
				# ffmpy3.FFmpeg(inputs={file_path: None}, outputs={file_path1: ['-ac','1','-ar','8000']}).run()
		pk_name=pk_name1
	else:
		with open(file_path, "wb") as f:
			f.write(content)


	src_path='/static/multi_data/{0}/{1}/{2}'.format(device_id, datetime.datetime.now().strftime('%Y-%m-%d'),pk_name)
	return src_path

def get_respone(kind,device_id,manufec):
	data_len=len(kind)
	zero_add=''
	command=''
	for x in range(4-len(hex(data_len))+2):
		zero_add+='0'
	data_len=zero_add+str.upper(hex(data_len)[2:])
	command=b'['+manufec.encode()+b'*'+device_id.encode()+b'*'+data_len.encode()+b'*'+kind.encode()+b']'
	return command

def respone_with_prarm(kind,device_id,param,result,manufec):
	data_len=len(kind)+1+len(param)
	zero_add=''
	for x in range(4-len(hex(data_len))+2):
		zero_add+='0'
	data_len=zero_add+str.upper(hex(data_len)[2:])
	command=b'['+manufec.encode()+b'*'+device_id.encode()+b'*'+data_len.encode()+b'*'+kind.encode()+b','+result.encode()+b']'
	return command

def three_analysis(row_data,rece_time,port,mesg_redis,device_id):
	# 数据分两部分，一是需要更新的数据，二是需要独立存储的数据，存储的数据需要符合表格的字段，也就是mesg_to_db_field。2020.08.31吕康宁
	add_to_db={'lbs': '0', 'mileage': '0', 'speed': '0', 'othermesg':{}, 'wifi': '0', 
			  'oil_use': '0', 'dirct': '0', 'scanner': '0', 'rssi': '0', 'efence_alarm': '0', 
			  'status': '0', 'remark': '0', 'heart_rate': '0', 'speed_alarm': '0', 'battery': '0', 
			  'blood_pres': '0', 'stop_time': '0','sos_alarm': '0', 'step_count': '0', 
			  'heart_alarm': '0', 'device_id':'0', 'dev_upload': '0', 'obd': '0', 'blood_alarm': '0', 
			  'lng': '0', 'serv_receive': '0', 'track_type': '0', 'location': '0', 'lat': '0', 'hard_verson': '0'}
	all_data={}
	response=b'0'
	data=row_data[1:-1].split(b',')
	d_head=data[0].decode().split('*')
	data_kind=d_head[3]
	if data_kind not in ['wdimg','TK','img']:
		data=row_data[1:-1].decode("utf8","ignore").split(',')

	manufec=d_head[0]
	data_kind=d_head[3]
	device_id=d_head[1]
	data_len=d_head[2]


	add_to_db['save_kind']='yes'
	# 用status字段存储在线离线信息，并存储到历史数据中，方便计算在线离线率2020.9.03吕康宁，有时间再梳理。
	all_data['on_off_line']='online'
	all_data['device_id']=device_id
	all_data['receive_port']=[port,'three']
	all_data['serv_receive']=rece_time


	if data_kind=='LK' and len(data)==4:
		all_data['step_count']=data[1]
		all_data['tumble']=data[2]
		all_data['battery']=data[3]

		response=b'['+manufec.encode()+b'*'+device_id.encode()+b'*0002*LK]'

	elif data_kind in ['TKQ','TKQ2']:
		response=b'['+manufec.encode()+b'*'+device_id.encode()+b'*'+data_len.encode()+b'*'+data_kind.encode()+b']'

	elif data_kind in ['UD','UD2','AL','AL_WCDMA','AL_TDSCDMA','AL_LTE','WT','UD_LTE','UD_WCDMA','UD_TDSCMDA']:
		up_date=data[1]
		up_time=data[2]
		format_time = '20%s-%s-%s %s:%s:%s'%(up_date[-2:],up_date[2:-2],up_date[:2],up_time[:2],up_time[2:-2],up_time[-2:])
		bj_time=int(time.mktime(time.strptime(format_time, "%Y-%m-%d %H:%M:%S")))+8*3600
		bj_time=datetime.datetime.fromtimestamp(bj_time).strftime("%Y-%m-%d %H:%M:%S")
		all_data['dev_upload']=bj_time

		if data[3]=='A':
			all_data['lng']=float(data[6])
			all_data['lat']=float(data[4])
		elif data[3]=='V':
			all_data['lng']='0'
			all_data['lat']='0'
		else:
			all_data['response']=response
			return all_data

		if data[8]!='22.0' and int(data[8])!=0:
			all_data['speed']=str(int(data[8]))

		all_data['dirct']=data[9]
		all_data['high']=data[10]
		all_data['gps_num']=data[11]
		all_data['rssi']=data[12]
		all_data['battery']=data[13]
		all_data['step_count']=data[14]
		all_data['tumble']=data[15]
		all_data['accuracy']=str(round(float(data[-1]),1))
		bit_data='{:032b}'.format(int(data[16],16))
		status_dict={31:'low_power',30:'out_efence',29:'in_efence',28:'ware_status',27:'dev_motion',
					 3:'ware_off',4:'move',15:'sos_alarm',16:'low_power_alarm',19:'remove',
					 20:'fall_down',21:'heart_alarm',17:'out_efence_alarm',18:'in_efence_alarm'}
		# print('alarm_mesg--------',bit_data)
		alarm_mesg=[]
		for k in status_dict:
			if bit_data[k]=='1':
					alarm_mesg.append(status_dict[k])
		if len(alarm_mesg)==0:
			alarm_mesg='0'
		else:
			alarm_mesg=str(alarm_mesg)
		all_data['sos_alarm']=alarm_mesg

		# all_data['rssi']=str({'gps_num':all_data.pop('gps_num'),'bds_num':'0','rssi':all_data['rssi']})
		lbs_num=data[17]

		# print(all_data)
		if lbs_num!='0':
			gsm_delay=data[18]
			MCC=data[19]
			MNC=data[20]
			lbs=data[21:21+int(lbs_num)*3]

			all_lbs=[]
			if len(lbs)%3!=0:
				lbs=lbs[0:len(lbs)-len(lbs)%3]
			for x in range(0,len(lbs),3):
				lbs_dict={'MNC':MNC,'MCC':MCC,'sid':lbs[x],'nid':lbs[x+1],'rssi':lbs[x+2]}
				all_lbs.append(lbs_dict)

			all_data['lbs']=str(all_lbs)
		# print('-------',len(data),lbs_num,data)
		if len(data)>21+int(lbs_num)*3:
			wifi_num=data[21+int(lbs_num)*3]
			if wifi_num!='' and wifi_num!='0':
				wifi=data[21+int(lbs_num)*3+1:-1]
				# print(wifi)
				all_wifi=[]
				if len(wifi)%3!=0:
					wifi=wifi[0:len(wifi)-len(wifi)%3]
				for x in range(0,len(wifi),3):
					wifi_dict={'ssid':wifi[x],'mac':wifi[x+1],'rssi':wifi[x+2]}
					all_wifi.append(wifi_dict)
				wifi_signal_max=pd.DataFrame(all_wifi)
				wifi_signal_max.sort_values(by=['rssi'],ascending=True,inplace=True)
				all_data['wifi']=str(all_wifi)

		if data_kind in ['AL','AL_WCDMA','AL_TDSCDMA','AL_LTE']:
			response=get_respone(data_kind,device_id,manufec)

	elif data_kind=='heart':
		
		all_data['heart_rate']=data[1]

	elif data_kind=='bpxy':
		# all_data['tall']=data[3]
		all_data['blood_pres']=str({'h_pres':data[1],'l_pres':data[2]})

		response=b'['+manufec.encode()+b'*'+device_id.encode()+b'*'+data_len.encode()+data_kind.encode()+b']'

	elif data_kind=='bphrt':
		all_data['blood_pres']=str({'h_pres':data[1],'l_pres':data[2]})
		all_data['heart_rate']=data[3]

		response=b'['+manufec.encode()+b'*'+device_id.encode()+b'*'+data_len.encode()+b'*'+data_kind.encode()+b']'
		
	elif data_kind=='TK':

		if int(data_len,16)>100:
			tk_data=data[1]
			replace_dict={b'}\x01':b'}',b'}\x02':b'[',b'}\x03':b']',b'}\x04':b',',b'}\x05':b'*'}
			# replace_dict={'7d01':'7d','7d02':'5b','7d03':'5d','7d04':'2c','7d05':'2a'}
			for repl_tag in replace_dict:
				tk_data=tk_data.replace(repl_tag,replace_dict[repl_tag])
			# tk_data=base64.b64encode(tk_data).decode()
			# tk_data=binascii.b2a_hex(tk_data).decode()
			now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
			all_data['voice']=save_to_file(device_id,'amr',tk_data,now)
			all_data['sender']='device'
			
			# response=get_respone(data_kind,device_id,'3G')
			# response=response=respone_with_prarm(data_kind,device_id,'1','1','3G')

		elif data[-1]==b'1':
			all_data['command_name']='voice'
			all_data['command_result']='success'
			# 放到底部统一处理，声音，图像，其他的命令结果一起
			# v_data=mesg_redis.get(device_id+'voice_dict')
			# if v_data!=None:
			# 	v_data=v_data.split(',')[1]
			# 	v_data=base64.b64decode(v_data)
			# 	# replace_dict1={b'}':b'}\x01',b'[':b'}\x02',b']':b'}\x03',b',':b'}\x04',b'*':b'}\x05'}
			# 	# for repl_tag in replace_dict1:
			# 	# 	v_data=v_data.replace(repl_tag,replace_dict1[repl_tag])
			# 	all_data['tk_mesg']=save_to_file(device_id,'amr',v_data)
			# 	all_data['sender']='request.user'
			# 	mesg_redis.delete(device_id+'voice_dict')

	elif data_kind=='ICCID':
		all_data['iccid']=data[1]

	elif data_kind in ['img','wdimg']:
		wdimg_data=data[-1]
		# replace_dict={'7d01':'7d','7d02':'5b','7d03':'5d','7d04':'2c','7d05':'2a'}
		# 数据反馈的结果为1，说明是系统给设备下发图片接收的结果
		if wdimg_data==b'1':

			all_data['command_name']='picture'
			all_data['command_result']='success'
			# 放到底部统一处理，声音，图像，其他的命令结果一起
			# img_data=mesg_redis.get(device_id+'picture')
			# if img_data!=None:
			# 	img_data=img_data.split(',')[1]
			# 	img_data=base64.b64decode(img_data)
			# 	all_data['img_data']=save_to_file(device_id,'jpeg',img_data)
			# 	all_data['sender']='request.user'
			# 	mesg_redis.delete(device_id+'picture')


		else:
			if len(wdimg_data)>50:
				replace_dict={b'}\x01':b'}',b'}\x02':b'[',b'}\x03':b']',b'}\x04':b',',b'}\x05':b'*'}
				for repl_tag in replace_dict:
					wdimg_data=wdimg_data.replace(repl_tag,replace_dict[repl_tag])
				# wdimg_data=base64.b64encode(wdimg_data).decode()
				# tk_data=binascii.b2a_hex(tk_data).decode()
				now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
				all_data['picture']=save_to_file(device_id,'jpeg',wdimg_data,now)
				all_data['sender']='device'

			response=respone_with_prarm('img',device_id,'1','1','3G')

	elif data_kind in ['RYTOKEN','CONFIG','RYIMEI']:
		print('data_kind',data_kind)
		add_to_db['save_kind']='no'
		
		# response=get_respone(data_kind,device_id,manufec)

	elif data_kind in ['MESSAGE',b'MESSAGE']:
		if data[-1]=='1':
			all_data['command_name']='text'
			all_data['command_result']='success'

	elif data_kind in three_command_result_dict:
		all_data['command_name']=three_command_result_dict[data_kind]
		command_result=''
		if command_result=='1' or command_result=='':
			command_result='success'
		elif command_result=='0':
			command_result='failed'

		all_data['command_result']=command_result


	all_data['track_type']=get_track_type(all_data)

	# handle_data=all_data.copy()
	# for x in handle_data:
	# 	if handle_data[x]=='0':
	# 		all_data.pop(x)

	# 下行数据处理，从redis取出服务器下发设备的数据，记录设备接收结果的反馈，多媒体数据进行本地存储，记录多媒体文件路劲，推给store模块存储和更新
	if all_data.get('command_result')!=None and all_data.get('command_name')!=None:
		comd_detail=mesg_redis.get(device_id+all_data['command_name'])
		print('comd_detail=========>',comd_detail)
		if comd_detail!=None:
			comd_detail=eval(comd_detail)
			comd_detail['command_result']=all_data['command_result']
			command_name=all_data['command_name']


			if command_name in ['voice','picture']:
				file_type={'voice':'amr','picture':'jpeg'}
				v_data=comd_detail['command_value']
				v_data=v_data.split(',')[1]
				v_data=base64.b64decode(v_data)
				send_time=comd_detail['send_time']
				file_path=save_to_file(device_id,file_type[command_name],v_data,send_time)
				all_data[command_name]=file_path
				comd_detail['command_value']=file_path
			else: 
				all_data[command_name]=comd_detail['command_value']

			# 存入redis，在store模块打包处理
			mesg_redis.delete(device_id+command_name)
			# 命令执行状态清理
			mesg_redis.delete(device_id+'command_excuting')
			mesg_redis.lpush(device_id+'command_log',str(comd_detail))

	add_to_db.update(all_data)
	othermesg={}
	for x in all_data:
		if x not in mesg_to_db_field:
			othermesg[x]=add_to_db.pop(x)

	add_to_db['othermesg']=str(othermesg)
	
	add_to_db['response']=response


	return add_to_db


def three_first_handle(datas):
	data_handled=[]
	if datas.startswith(b'[') and datas.endswith(b']'):
		datas=datas.split(b']')
		datas.pop()
		for data in datas:
			data=data+b']'
			data_handled.append(data)
		return {'normal_data':data_handled}
	else:
		return 'buffer_data'
								# '(?P<date>\w{1,10}),(?P<time>\w{1,10}),(?P<track_type>\w{1,10}),(?P<lat>\d+\.\d+),(?P<lat_tag>\w{1,10}),(?P<lng>\d+\.\d+),(?P<lng_tag>\w{1,10}),(?P<speed>\d+\.\d+),(?P<dirct>\d+|\d+\.\d+),(?P<high>[-]\d+|\d+|\d+\.\d+),(?P<gps_num>\w{1,10}),(?P<rssi>\w{1,10}),(?P<battery>\w{1,10}),(?P<step_count>\w{1,10}),(?P<tumble>\w{1,10}),(?P<status>\w{1,10}),(?P<lbs_num>\w{1,10}),'
# ttdd=b'[3G*9613051350*0116*UD_LTE,040120,120233,A,22.617001,N,114.034809,E,22.0,351.839,-14.288,20,100,15,5220,0,00000001,1,1,460,11,30560,125675569,100,5,qccEA302,90:86:9b:1b:11:80,-52,EA302,48:0e:ec:32:3f:d9,-25,,f8:c3:9e:d6:6a:09,-57,SZ98-2.4G,d0:76:e7:0f:e3:b3,-66,Quyi,f8:c3:9e:d6:6a:04,-60,6.2807717]'
# hognlian=b'[3G*1210013000*0067*UD,140120,112456,A,22.616758,N,114.034653,E,0.00,251.49,102,8,100,77,0,0,00000001,1,0,460,0,9380,4502,1]'
# hognlian1=b'[3G*1210013000*007f*AL,140120,200159,V,00.000000,N,000.000000,E,0.00,0.00,0,0,100,74,0,0,00010009,3,0,460,0,9380,4501,255,9380,4632,20,9380,5303,19]'
# print(three_analysis(hognlian))
# data=b'[3G*9612281103*0180*CONFIG,TY:g75,UL:300,SY:0,CM:1,WT:1,HR:0,TB:2,AB:0,CS:1,PP:2,HH:1,TR:0,MO:0,FL:0,VD:0,DD:0,SD:0,XY:0,WF:0,WX:0,PH:1,RW:0,MT:1,XD:0,XL:0,YF:0,SM:0,HF:1,JX:0,WL:0,BQ:0,QQ:0,DL:0,HT:1,PB:0,RS:240240,DW:1,SS:0,OF:1,IN:0,JT:0,GH:0,BT:0,CL:0,FA:1,FD:1,CT:1,SO:1,ME:1,LR:1,TO:1,RR:1,AC:1,DC:1,XM:1,YJ:1,RY:1,RD:0,LG:1,EM:0,VL:0,PV:1,FY:0,VR:G4E_EMMC_IPS_240_5M_650_YDE_20190604_15.02.00,DS:0]'
# data1=b'[3G*9612281103*0016*RYIMEI,863996122811032]'